package db

import (
	"context"
	"errors"
	"fmt"
	"gitee.com/bojinyuan/pkg-manager-go/pkg/db/drivers"
	"github.com/redis/go-redis/v9"
	"log"

	"sync"
	"time"

	"gorm.io/gorm"
)

var mu sync.Mutex

// InitRedisDB 初始化 Redis 客户端
func InitRedisDB(host string, port int) (*redis.Client, error) {
	// 全局 Redis 连接存在，则直接返回
	if RedisDb != nil {
		return RedisDb, nil
	}

	// 创建 Redis 客户端
	Addr := fmt.Sprintf("%s:%d", host, port)
	client := redis.NewClient(&redis.Options{
		Addr:     Addr, // Redis 地址
		Password: host, // 密码
		DB:       port, // 数据库编号
	})

	// 测试连接
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	_, err := client.Ping(ctx).Result()
	if err != nil {
		log.Fatalf("failed to connect to redis: %v", err)
	}

	log.Printf("db-Connected to Redis:success:%s\n", Addr)
	RedisDb = client // 设置全局 Redis 连接 todo 这两种方式都可以
	if err != nil {
		return nil, err
	}

	return client, nil
}

// InitGormDB 封装具体的数据库连接逻辑
func InitGormDB(driver, host, userName, password, database string, port int, maxIdle, maxOpen, maxLifetime int) (*gorm.DB, error) {
	mu.Lock()
	defer mu.Unlock()

	if GormDb != nil {
		return GormDb, nil
	}

	var dialector gorm.Dialector
	switch driver {
	case "mysql": // mysql 数据库
		dialector = drivers.NewMysqlDialector(host, userName, password, database, port) //mysql数据库
	case "postgres": // postgres 数据库
		dialector = drivers.NewPostgresDialector(host, userName, password, database, port) //postgres数据库
	case "gauss": // postgres 数据库
		dialector = drivers.NewGaussDialector(host, userName, password, database, port) //华为高斯数据库
	case "kingbase": // kingbase 数据库-人大金仓
		dialector = drivers.NewKingbaseDialector(host, userName, password, database, port) //人大金仓数据库
	case "dameng":
		dialector = drivers.NewDmDialector(host, userName, password, database, port) //达梦数据库
	case "gbase8s":
		dialector = drivers.NewGBase8sDialector(host, userName, password, database, port) //南大通用数据库
	case "gbase8a":
		dialector = drivers.NewGBase8aDialector(host, userName, password, database, port) //南大通用数据库
	default:
		return nil, errors.New("db-gorm Database connection not found")
	}

	// 日志输出到文件 todos
	db, err := gorm.Open(dialector, &gorm.Config{})
	if err != nil {
		return nil, err
	}

	// 自动迁移表结构
	//go func() {
	//	err := autoMigrate(db)
	//	if err != nil {
	//		log.Printf("auto migrate failed: %v", err)
	//	}
	//}()
	// 设置连接池参数
	sqlDB, err := db.DB()
	if err != nil {
		return nil, err
	}
	sqlDB.SetMaxIdleConns(maxIdle)                                     //设置最大空闲连接数
	sqlDB.SetMaxOpenConns(maxOpen)                                     //设置可打开的最大连接数为 100 个
	sqlDB.SetConnMaxLifetime(time.Duration(maxLifetime) * time.Second) //设置一个连接空闲后在多长时间内可复用

	log.Printf("db-gorm Database connected success: %s", driver)

	// 添加到全局管理器
	GormDb = db // 设置全局数据库连接
	if err != nil {
		return nil, err
	}
	return db, nil
}

// ConcreteObserver 具体的观察者
type ConcreteObserver struct {
	name string
}
